﻿#include "endingpanel.h"
#include "gamepanel.h"
#include "ui_gamepanel.h"
#include <QPainter>
#include <QRandomGenerator>
#include <QDebug>
#include <QPropertyAnimation>
GamePanel::GamePanel(QWidget *parent)
    : QMainWindow(parent)
    ,ui(new Ui::GamePanel)
{
    setFixedSize(1000,650);
    ui->setupUi(this);
    //初始化按钮组
    initButtonGroup();
    //1.设置背景图
    int num = QRandomGenerator::global()->bounded(10);
    QString pixmap=QString(":/images/background-%1.png").arg(num+1);
    m_bkImage.load(pixmap);
    //2.标题
    this->setWindowTitle("欢乐斗地主");
    //3.实例化玩家
    gameControlInit();
    //4更新分数
    updateScore();

    //切割卡牌图片
    initCardMap();
    //初始化玩家扑克牌及头像位置
    initPlayerContext();

    //  初始化游戏场景
    initGameScene();
    //初始化定时器
    m_timer=new QTimer(this);
    connect(m_timer,&QTimer::timeout,this,&GamePanel::onDispatchCard);
    //初始化玩家得分窗口显示
    m_animation=new AnimationWindow(this);
    //初始化倒计时窗口
    initCountDown();
    //实例化多媒体
    m_bgm=new BGMControl(this);
}

GamePanel::~GamePanel()
{
    delete ui;
}

void GamePanel::gameControlInit()
{
    m_gameCtl=new GameControl(this);
    m_gameCtl->playerInit();
    Robot* leftRobot=m_gameCtl->getLeftRobot();
    Robot* rightRobot=m_gameCtl->getRightRobot();
    UserPlayer* user=m_gameCtl->getUserPlayer();

    m_playerList << leftRobot<<rightRobot<<user;
    connect(m_gameCtl,&GameControl::playerStatusChanged,this,&GamePanel::onPlayerStatusChanged);
    connect(m_gameCtl,&GameControl::notifyGrabLordBet,this,&GamePanel::onGrabLordBet);
    connect(m_gameCtl,&GameControl::gameStatusChanged,this,&GamePanel::gameStatusPrecess);
    connect(m_gameCtl,&GameControl::notifyPlayhand,this,&GamePanel::onDisposePlayHand);

    connect(leftRobot,&Robot::notifyPickCards,this,&GamePanel::disposCard);
    connect(rightRobot,&Robot::notifyPickCards,this,&GamePanel::disposCard);
    connect(user,&Robot::notifyPickCards,this,&GamePanel::disposCard);
}

void GamePanel::updateScore()
{
    ui->scorepanel->setScores(
                m_playerList[0]->getScore(),
                m_playerList[1]->getScore(),
            m_playerList[2]->getScore());
}

void GamePanel::initCardMap()
{
    //1.加载大图
    QPixmap pixmap(":/images/card.png");
    //2.计算每张图片大小
    m_cardSize.setWidth(pixmap.width()/13);
    m_cardSize.setHeight(pixmap.height()/5);

    m_cardBackImage = pixmap.copy(2*m_cardSize.width(),4*m_cardSize.height(),m_cardSize.width(),m_cardSize.height());

    int count=0;
    for(int i=0,suit=Card::Suit_Begin+1;suit<Card::Suit_End;suit++,i++)
    {
        for(int j=0,point=Card::Card_Begin+1;point<Card::Card_SJ;point++,j++,count++)
        {
            Card newcard((Card::CardPoint)point,(Card::CardSuit)suit);
            CardPanel* newcardpanel=new CardPanel(this);
            newcardpanel->setCard(newcard);
            QPixmap front = pixmap.copy(j*m_cardSize.width(),i*m_cardSize.height(),m_cardSize.width(),m_cardSize.height());
            newcardpanel->setImage(front,m_cardBackImage);
            newcardpanel->hide();
            m_cardPanelMap.insert(newcard,newcardpanel);
            connect(newcardpanel,&CardPanel::cardSelect,this,&GamePanel::onCardSelect);
            //qDebug()<<"count:"<<count;
        }
    }

    Card c;
    c.setPoint(Card::Card_SJ);
    c.setSuit(Card::Suit_Begin);
    QPixmap front = pixmap.copy(0,4*m_cardSize.height(),m_cardSize.width(),m_cardSize.height());
    CardPanel* newcardpanel=new CardPanel(this);
    newcardpanel->setCard(c);
    newcardpanel->setImage(front,m_cardBackImage);
    newcardpanel->hide();
    m_cardPanelMap.insert(c,newcardpanel);
    connect(newcardpanel,&CardPanel::cardSelect,this,&GamePanel::onCardSelect);

    Card d;
    d.setPoint(Card::Card_BJ);
    d.setSuit(Card::Suit_Begin);
    QPixmap front2 = pixmap.copy(m_cardSize.width(),4*m_cardSize.height(),m_cardSize.width(),m_cardSize.height());
    CardPanel* newcardpanel2=new CardPanel(this);
    newcardpanel2->setCard(d);
    newcardpanel2->setImage(front2,m_cardBackImage);
    newcardpanel2->hide();
    m_cardPanelMap.insert(d,newcardpanel2);
    connect(newcardpanel2,&CardPanel::cardSelect,this,&GamePanel::onCardSelect);
}

void GamePanel::initButtonGroup()
{
    ui->btnGroup->ButtonInit();
    ui->btnGroup->selectPanel(ButtonGroup::Start);

    connect(ui->btnGroup,&ButtonGroup::start,this,[=](){
        ui->btnGroup->selectPanel(ButtonGroup::Empty);
        gameStatusPrecess(GameControl::DispatchCard);
        //播放背景音乐
        m_bgm->startBGM(80);

    });
    connect(ui->btnGroup,&ButtonGroup::play,this,&GamePanel::onUserPlayCard);
    connect(ui->btnGroup,&ButtonGroup::pass,this,&GamePanel::onUserPass);
    connect(ui->btnGroup,&ButtonGroup::betPoint,this,[=](int point){
        m_gameCtl->getUserPlayer()->grabLordBet(point);

    });
}

void GamePanel::initPlayerContext()
{
    //1.玩家放置扑克牌的区域
    const QRect cardsRect[] =
        {
            // x, y, width, height
            QRect(90, 130, 100, height() - 200),                    // 左侧机器人
            QRect(rect().right() - 190, 130, 100, height() - 200),  // 右侧机器人
            QRect(250, rect().bottom() - 120, width() - 500, 100)   // 当前玩家
        };
    //qDebug()<<"qrect:"<<QString::number(rect().right() - 190)<<"user:"<<QString::number(rect().bottom() - 120);
    //2.玩家出牌的区域
    const QRect playHandRect[] =
        {
            QRect(260, 150, 100, 100),                              // 左侧机器人
            QRect(rect().right() - 360, 150, 100, 100),             // 右侧机器人
            QRect(150, rect().bottom() - 290, width() - 300, 105)   // 当前玩家
        };
    //3.玩家头像显示位置
    const QPoint roleImgPos[] =
        {
            QPoint(cardsRect[0].left()-80, cardsRect[0].height() / 2 + 20),     // 左侧机器人
            QPoint(cardsRect[1].right()+10, cardsRect[1].height() / 2 + 20),    // 右侧机器人
            QPoint(cardsRect[2].right()-10, cardsRect[2].top() - 10)            // 当前玩家
        };
    //计算出非机器人玩家的index
    int index=m_playerList.indexOf(m_gameCtl->getUserPlayer());
    for(int i=0;i<m_playerList.size();i++)
    {

       Player* player = m_playerList[i];
       struct PlayerContext context;
       context.align=i==index?Horizontal:Vertical;
       context.isFront=i==index?true:false;
       context.cardRect=cardsRect[i];
       context.playHandRect=playHandRect[i];
       context.info=new QLabel(this);
       context.info->resize(160,98);
       context.info->hide();
       //将提示信息显示到出牌区域中心，计算坐标
       QRect rect=playHandRect[i];
       QPoint point(rect.x()+(rect.width()-context.info->rect().width())/2,
                    rect.y()+(rect.height()-context.info->height())/2);
       context.info->move(point);

       context.roleImg=new QLabel(this);
       context.roleImg->resize(84,120);
       context.roleImg->hide();
       context.roleImg->move(roleImgPos[i]);
       m_contextMap.insert(player,context);
    }
}

void GamePanel::initGameScene()
{
    //1.发牌区的扑克牌
    m_baseCard=new CardPanel(this);
    m_baseCard->setImage(m_cardBackImage,m_cardBackImage);
    //2.发牌过程中的扑克牌
    m_moveCard=new CardPanel(this);
    m_moveCard->setImage(m_cardBackImage,m_cardBackImage);
    //3.3张底牌
    for(int i=0;i<3;i++)
    {
        CardPanel* panel=new CardPanel(this);
        panel->setImage(m_cardBackImage,m_cardBackImage);
        panel->hide();
        m_last3Card.push_back(panel);
    }
    m_baseCardPos=QPoint((width()-m_cardSize.width())/2,(height()-m_cardSize.height())/2-100);
    m_baseCard->move(m_baseCardPos);
    m_moveCard->move(m_baseCardPos);
    int base=(width()-3*m_cardSize.width()-2*10)/2;
    for(int i=0;i<3;i++)
    {
        m_last3Card[i]->move(base+(m_cardSize.width()+10)*i,20);

    }

}

void GamePanel::gameStatusPrecess(GameControl::GameStatus status)
{
    m_gameStatus=status;
    switch(status)
    {
    case GameControl::CallingLord:
    {

        QVector<Card> last3Card=m_gameCtl->getSurplusCards().toCardList();
        for(int i=0;i<last3Card.size();i++)
        {
           QPixmap front = m_cardPanelMap[ last3Card.at(i) ]->getImage();
           m_last3Card[i]->setImage(front,m_cardBackImage);
           m_last3Card[i]->setFrontSide(false);
           m_last3Card[i]->move((width()-40*2-m_baseCard->width()*3)/2+i*(40+m_baseCard->width()),50);
           m_last3Card[i]->hide();
        }
        m_gameCtl->startLordCard();
        break;
    }
    case GameControl::DispatchCard:
        startDispatchCard();
        break;
    case GameControl::PlayingHnad:
    {
        //隐藏发牌区的底牌和移动的牌
        m_baseCard->hide();
        m_moveCard->hide();
        //显示留给地主的三张牌
        int space=40;
        int x=(width()-3*m_baseCard->width()-2*space)/2;
        int y=40;
        for(int i=0;i<m_last3Card.size();++i)
        {
            m_last3Card[i]->move(x+i*(space+m_baseCard->width()),y);
            m_last3Card[i]->setFrontSide(true);
            m_last3Card[i]->show();
        }
        //隐藏各个玩家抢地主过程中的提示信息
        for(int i=0;i<m_playerList.size();++i)
        {
           PlayerContext& context =m_contextMap[m_playerList[i]];
           context.info->hide();
           //显示各个玩家头像
           QPixmap pixmap=loadRoleImage(m_playerList[i]->getSex(),m_playerList[i]->getDirection(),m_playerList[i]->getRole());
           context.roleImg->setPixmap(pixmap);
           context.roleImg->show();
        }
    }
        break;
    default:
        break;
    }

}

void GamePanel::startDispatchCard()
{
    //重置每张卡牌属性
    for(auto i=m_cardPanelMap.begin();i!=m_cardPanelMap.end();i++)
    {
        i.value()->setFrontSide(true);
        i.value()->setSelected(false);
        i.value()->hide();
    }

    //隐藏上局三张底牌
    for(int i=0;i<3;i++)
    {
        m_last3Card[i]->hide();
    }

    //重置玩家信息
    int index=m_playerList.indexOf(m_gameCtl->getUserPlayer());
    for(int i=0;i<m_playerList.size();i++)
    {
        m_contextMap[m_playerList.at(i)].lastCards.clear();

        //m_contextMap[m_playerList.at(i)].info->hide();qDebug()<<"jjjj";
        //m_contextMap[m_playerList.at(i)].roleImg->hide();
        m_contextMap[m_playerList.at(i)].isFront=i==index?true:false;
    }
    //重置所有玩家手牌数据
    m_gameCtl->resetCardData();
    //显示底牌
    m_baseCard->show();
    //隐藏按钮面板
    ui->btnGroup->selectPanel(ButtonGroup::Empty);
    //启动定时器
    m_timer->start(10);
    //播放发牌音效
    m_bgm->playAssistMusic(BGMControl::Dispatch);
}

void GamePanel::onDispatchCard()
{
    //记录扑克牌的位置
    static int curMovePos=0;
    //当前玩家
    Player* curplayer=m_gameCtl->getCurPlayer();
    //移动扑克牌
    if(curMovePos>=100)
    {
        Card card=m_gameCtl->takeOneCard();
        curplayer->storeDispatchCard(card);
        Cards cs(card);
        disposCard(curplayer,cs);
        m_gameCtl->setCurPlayer(curplayer->getNextPlayer());

        curMovePos=0;
        curplayer=m_gameCtl->getCurPlayer();

        cardMoveStep(curplayer,curMovePos);
        if(m_gameCtl->getSurplusCards().cardcount()==3)
        {
            m_timer->stop();
            gameStatusPrecess(GameControl::CallingLord);
            m_bgm->stopAssisMusic();
            return;
        }
    }
    cardMoveStep(curplayer,curMovePos);
    curMovePos+=15;


}

void GamePanel::cardMoveStep(Player* player,int curMovePos)
{
    //得到每个玩家对应的扑克牌展示区域
    QRect rect=m_contextMap[player].cardRect;
    //qDebug()<<"rect.x"<<QString::number(rect.x())<<"rect.y"<<QString::number(rect.y());
    int unit[]={
        (m_baseCardPos.x()-rect.right())/100,
        (rect.left()-m_baseCardPos.x())/100,
        (rect.top()-m_baseCardPos.y())/100
    };
    QPoint pos[]={
            QPoint(m_baseCardPos.x()-unit[0]*curMovePos,m_baseCardPos.y()),
            QPoint(m_baseCardPos.x()+unit[1]*curMovePos,m_baseCardPos.y()),
            QPoint(m_baseCardPos.x(),m_baseCardPos.y()+unit[2]*curMovePos)
    };
    int index=m_playerList.indexOf(player);

    m_moveCard->move(pos[index]);

    if(curMovePos==0)
    {
        m_moveCard->show();
    }
    if(curMovePos==100)
    {
        m_moveCard->hide();
    }


}

void GamePanel::disposCard(Player *player, Cards &cards)
{
    QVector<Card> cardList=cards.toCardList();
    for(int i=0;i<cardList.size();i++)
    {
        CardPanel* panel=m_cardPanelMap[cardList[i]];
        panel->setOwner(player);
    }
    //更新扑克牌显示
    updatePlayerCards(player);

}

void GamePanel::updatePlayerCards(Player *player)
{
    //打出手牌后更新玩家手里的牌
    Cards cards=player->getCards();
    QVector<Card> cardList=cards.toCardList();
    //
    m_cardsRect=QRect();
    //清空窗口与位置的对应关系
    m_userCards.clear();
    int cardSpace=20;
    QRect rect=m_contextMap[player].cardRect;
    for(int i=0;i<cardList.size();i++)
    {
         CardPanel* panel= m_cardPanelMap[cardList[i]];
         panel->show();
         panel->raise();
         panel->setFrontSide(m_contextMap[player].isFront);
         if(m_contextMap[player].align==Horizontal)
         {
             int x=(rect.width()-(cardList.size()-1)*cardSpace-panel->width())/2+rect.x();
             int y=rect.y()+(rect.height()-panel->height())/2;
             if(panel->isSelected())
             {
                 y-=10;
             }
             panel->move(x+i*cardSpace,y);
             //panel->show();
             m_cardsRect=QRect(x,y,cardSpace*i+m_baseCard->width(),m_baseCard->height());
             int curWidth=0;
             //如果是最后一张牌
             if(i==cardList.size()-1)
             {
                 curWidth=m_cardSize.width();

             }
             else
             {
                 curWidth=cardSpace;

             }
             QRect rect(x+i*cardSpace,y,curWidth,m_baseCard->height());
             m_userCards.insert(panel,rect);
         }
         else
         {
             int x=(rect.x()+(rect.width()-panel->width())/2);
             int y=(rect.height()-(cardList.size()-1)*cardSpace-panel->height())/2+rect.y();
             panel->move(x,y+i*cardSpace);
         }
    };
    //显示玩家打出的牌
    QRect playRect=m_contextMap[player].playHandRect;
    Cards lastCards=m_contextMap[player].lastCards;
    if(!lastCards.isEmpty())
    {
        QVector<Card> lastCardList=lastCards.toCardList();
        for(int i=0;i<lastCardList.size();i++)
        {
            Card card=lastCardList[i];
            CardPanel* panel=m_cardPanelMap[card];
            panel->setFrontSide(true);
            panel->raise();
            if(m_contextMap[player].align==Horizontal)
            {
                int x=playRect.x()+(playRect.width()-cardSpace*(lastCardList.size()-1)-panel->width())/2;
                int y=playRect.y()+(playRect.height()-panel->height())/2;
                panel->move(x+cardSpace*i,y);

            }
            else
            {
                int x=playRect.x()+(playRect.width()-panel->width())/2;
                int y=playRect.y();
                panel->move(x,y+cardSpace*i);
            }
            panel->show();

        }
    }


}

void GamePanel::onPlayerStatusChanged(Player *player,GameControl::PlayerStatus status)
{

    switch(status)
    {
    case GameControl::ThinkingForCallLord:
        if(player==m_gameCtl->getUserPlayer())
        {
            ui->btnGroup->selectPanel(ButtonGroup::CallLord);
        }
        break;
    case GameControl::ThinkingForPlayHand:
        //隐藏上一轮打出的牌
        hidePlayerDropCards(player);
        //如果是用户玩家，有两个界面选择，一是上轮自己的牌最大继续出牌PlayCard，二是管别人的牌PassOrPlay。
        if(player==m_gameCtl->getUserPlayer())
        {
            Player* pendPlayer=m_gameCtl->getPendPlayer();
            if(m_gameCtl->getUserPlayer()==pendPlayer||pendPlayer==nullptr)
            {
                ui->btnGroup->selectPanel(ButtonGroup::PlayCard);
            }
            else
            {
                ui->btnGroup->selectPanel(ButtonGroup::PassOrPlay);
            }
        }
        else
        {
            ui->btnGroup->selectPanel(ButtonGroup::Empty);
        }
        break;
    case GameControl::winning:
        m_bgm->stopBGM();
        m_contextMap[m_gameCtl->getLeftRobot()].isFront=true;
        m_contextMap[m_gameCtl->getRightRobot()].isFront=true;
        updatePlayerCards(m_gameCtl->getLeftRobot());
        updatePlayerCards(m_gameCtl->getRightRobot());
        updateScore();
        m_gameCtl->setCurPlayer(player);
        showEndingScorePanel();

        break;
    default:
        break;
    }
}

void GamePanel::onGrabLordBet(Player *player, int point, bool flag)
{
    PlayerContext context=m_contextMap[player];
    if(point==0)
    {
        context.info->setPixmap(QPixmap(":/images/buqinag.png"));
    }
    else
    {
        if(flag)
        {
            context.info->setPixmap(QPixmap(":/images/jiaodizhu.png"));
        }
        else
        {
            context.info->setPixmap(QPixmap(":/images/qiangdizhu.png"));
        }
        showAnimation(AnimationType::bet, point);
    }
    context.info->show();

    //显示叫地主的分数
    m_bgm->playerRobLordMusic(point,(BGMControl::RoleSex)player->getSex(),flag);
}

void GamePanel::showAnimation(GamePanel::AnimationType type, int pt)
{
    switch(type)
    {
    case AnimationType::liandui:
        m_animation->setFixedSize(250,150);
        m_animation->move((width()-m_animation->width())/2,200);
        m_animation->showSequence((AnimationWindow::Type)type);
        break;
    case AnimationType::shunzi:
        m_animation->setFixedSize(250,150);
        m_animation->move((width()-m_animation->width())/2,200);
        m_animation->showSequence((AnimationWindow::Type)type);
        break;
    case AnimationType::plane:
        m_animation->setFixedSize(800,75);
        m_animation->move((width()-m_animation->width())/2,200);
        m_animation->showPlane();
        break;
    case AnimationType::bomb:
        m_animation->setFixedSize(180,200);
        m_animation->move((width()-m_animation->width())/2,(height()-m_animation->height())/2-70);
        m_animation->showBomb();
        break;
    case AnimationType::jokerbomb:
        m_animation->setFixedSize(250,200);
        m_animation->move((width()-m_animation->width())/2,(height()-m_animation->height())/2-70);
        m_animation->showJokerBomb();
        break;
    case AnimationType::bet:
        m_animation->setFixedSize(160,98);
        m_animation->move((width()-m_animation->width())/2,(height()-m_animation->height())/2-200);
        m_animation->showBetScore(pt);
        break;
    }
    m_animation->show();
}

void GamePanel::onDisposePlayHand(Player *player, Cards &cards)
{

    //存储玩家这一轮打出的牌
    auto it=m_contextMap.find(player);
    it->lastCards=cards;

    //根据牌型播放游戏特效，判断牌型
    PlayHand hand(cards);
    PlayHand::HandType type= hand.getHandType();
    if(type==PlayHand::Hand_Plane||
            type==PlayHand::Hand_Plane_Two_Pair||
            type==PlayHand::Hand_Plane_Two_Single)
    {
        showAnimation(plane);
    }
    else if(type==PlayHand::Hand_Seq_Pair)
    {
        showAnimation(liandui);
    }
    else if(type==PlayHand::Hand_Seq_Single)
    {
        showAnimation(shunzi);
    }
    else if(type==PlayHand::Hand_Bomb)
    {
        showAnimation(bomb);
    }
    else if(type==PlayHand::Hand_Bomb_Jokers)
    {
        showAnimation(jokerbomb);
    }
    //如果打出的牌为空，提示信息显示“不要”
    if(cards.isEmpty())
    {
        it->info->setFixedSize(160,98);
        it->info->setPixmap(QPixmap(":/images/pass.png"));
        it->info->show();
        m_bgm->playPassMusic((BGMControl::RoleSex)player->getSex());
    }
    //根据牌型播放提示音
    else
    {
        if(m_gameCtl->getPendPlayer()==player || m_gameCtl->getPendPlayer()==nullptr)
        {
            m_bgm->playCardMusic(cards,true,(BGMControl::RoleSex)player->getSex());
        }
        else
        {
            m_bgm->playCardMusic(cards,false,(BGMControl::RoleSex)player->getSex());
        }
    }
    //更新玩家手牌
    updatePlayerCards(player);
    //播放提示音乐
    if(player->getCards().cardcount()==2)
    {
        m_bgm->playLastMusic(BGMControl::Last2,(BGMControl::RoleSex)player->getSex());
    }
    else if(player->getCards().cardcount()==1)
    {
        m_bgm->playLastMusic(BGMControl::Last1,(BGMControl::RoleSex)player->getSex());
    }


}

void GamePanel::hidePlayerDropCards(Player *player)
{
    auto it = m_contextMap.find(player);
    if(it!=m_contextMap.end())
    {
        if(it->lastCards.isEmpty())
        {
            it->info->hide();
        }
        else
        {
            Cards cards=it->lastCards;
            QVector<Card> cardlist= cards.toCardList();
            for(int i=0;i<cardlist.size();i++)
            {
                Card card=cardlist[i];
                //m_cardPanelMap[card]->hide();
                QMap<Card,CardPanel*>::iterator panel= m_cardPanelMap.find(card);
                (*panel)->hide();
            }
        }
        it->lastCards.clear();
    }
}

QPixmap GamePanel::loadRoleImage(Player::Sex sex, Player::Direction direct, Player::Role role)
{
    QVector<QString> lordMan;
    QVector<QString> lordWoMan;
    QVector<QString> farmerMan;
    QVector<QString> farmerWodMan;
    lordMan<<QString(":/images/lord_man_1.png")<<QString(":/images/lord_man_2.png");
    lordWoMan<<QString(":/images/lord_woman_1.png")<<QString(":/images/lord_woman_2.png");
    farmerMan<<QString(":/images/farmer_man_1.png")<<QString(":/images/farmer_man_2.png");
    farmerWodMan<<QString(":/images/farmer_woman_1.png")<<QString(":/images/farmer_woman_2.png");

    QImage image;
    if(sex==Player::Man&&role==Player::lord)
    {
        image.load(lordMan[QRandomGenerator::global()->bounded(2)]);
    }
    else if(sex==Player::Woman &&role==Player::lord)
    {
        image.load(lordWoMan[QRandomGenerator::global()->bounded(2)]);
    }
    else if(sex==Player::Man&&role==Player::farmer)
    {
        image.load(farmerMan[QRandomGenerator::global()->bounded(2)]);
    }
    else if(sex==Player::Woman&&role==Player::farmer)
    {
        image.load(farmerWodMan[QRandomGenerator::global()->bounded(2)]);
    }
    QPixmap pixmap;
    if(direct==Player::left)
    {
        pixmap=QPixmap::fromImage(image);
    }
    else
    {
        pixmap=QPixmap::fromImage(image.mirrored(true,false));
    }
    return pixmap;

}

void GamePanel::onCardSelect(Qt::MouseButton button)
{
    //判断是不是出牌状态
    if(m_gameStatus==GameControl::CallingLord||m_gameStatus==GameControl::DispatchCard)
    {
        return;
    }
    //判断是不是用户的牌
    CardPanel* panel=(CardPanel*)sender();
    Player* player=panel->getOwner();
    if(player!=m_gameCtl->getUserPlayer())
    {
        return;
    }
    //保存选中的牌的窗口对象
    m_curSelCard=panel;
    if(button==Qt::LeftButton)
    {
        //设置扑克牌选中状态，之前是未选中则选中，之前是选中则取消选中
        panel->setSelected(!panel->isSelected());
         //更新扑克牌的窗口显示
        updatePlayerCards(player);
        //保存或删除扑克牌窗口对象
        QSet<CardPanel*>::const_iterator it= m_selectCards.find(panel);
        if(it==m_selectCards.end())
        {
            m_selectCards.insert(panel);
        }
        else
        {
            m_selectCards.erase(it);
        }
        m_bgm->playAssistMusic(BGMControl::SelectCard);
    }
    else if(button==Qt::RightButton)
    {
        onUserPlayCard();
    }
    //判断是左键还是右键
}

void GamePanel::onUserPlayCard()
{
    //判断当前是不是出牌状态
    if(m_gameStatus!=GameControl::PlayingHnad)
    {
        return;
    }
    //判断玩家是不是用户玩家
    if(m_gameCtl->getCurPlayer()!=m_gameCtl->getUserPlayer())
    {
        return;
    }
    //判断牌是否为空
    if(m_selectCards.size()==0)
    {
        return;
    }
    //判断牌型
    Cards cards;
    for(QSet<CardPanel*>::iterator it=m_selectCards.begin();it!=m_selectCards.end();it++)
    {
        Card card=(*it)->getCard();
        cards.add(card);
    }
    PlayHand hand(cards);
    PlayHand::HandType type=hand.getHandType();
    if(type==PlayHand::Hand_Unknown)
    {
        return;
    }
    //判断上轮出牌玩家不是自己
    if(m_gameCtl->getPendPlayer()!=m_gameCtl->getUserPlayer())
    {
        //获得上轮出的牌
        Cards cards1=m_gameCtl->getPendCards();
        //判断能否压住上家牌
        if(!hand.canBeat(PlayHand(cards1)))
        {
            //压不住
            return;
        }
    }
    m_countDown->stopCountDown();
    //通过玩家对象出牌
    m_gameCtl->getUserPlayer()->playHand(cards);
    //清空容器
    m_selectCards.clear();

}

void GamePanel::onUserPass()
{
    m_countDown->stopCountDown();
    //判断是不是用户玩家
    Player* useryer=m_gameCtl->getUserPlayer();
    Player* curplayer=m_gameCtl->getCurPlayer();
    if(useryer!=curplayer)
    {
        return;
    }
    //判断是不是上次出牌玩家
    if(useryer==m_gameCtl->getPendPlayer()||m_gameCtl->getPendPlayer()==nullptr)
    {
        return;
    }
    //打出一个空的Cards对象
    Cards empty;
    useryer->playHand(empty);
    //将选中的牌设置为未选中状态，并清空选择的容器
    for(QSet<CardPanel*>::iterator it=m_selectCards.begin();it!=m_selectCards.end();it++)
    {
        (*it)->setSelected(false);
    }
    m_selectCards.clear();

    //更新手牌显示
    updatePlayerCards(useryer);
}

void GamePanel::showEndingScorePanel()
{

        bool isLord=m_gameCtl->getUserPlayer()->getRole()==Player::lord?true:false;
        bool isWin=m_gameCtl->getUserPlayer()->getWin();
        EndingPanel* panel=new EndingPanel(isLord,isWin,this);
        panel->move((width()-panel->width())/2,-panel->height());
        panel->setScore(m_gameCtl->getLeftRobot()->getScore(),
                        m_gameCtl->getRightRobot()->getScore(),
                        m_gameCtl->getUserPlayer()->getScore());
        panel->show();
        m_bgm->playEndingMusic(isWin);
    //将窗口设置为从上方落下
    //定义动画类
    QPropertyAnimation* animation=new QPropertyAnimation(panel,"geometry",this);
    //设置动画持续时间
    animation->setDuration(1500);
    //设置窗口起始位置和结位置
    animation->setStartValue(QRect(panel->x(),panel->y(),panel->width(),panel->height()));
    animation->setEndValue(QRect((width()-panel->width())/2,(height()-panel->height())/2,panel->width(),panel->height()));
    //设置窗口运动曲线
    animation->setEasingCurve(QEasingCurve(QEasingCurve::OutBounce));
    //播放动画效果
    animation->start();
    //按下继续游戏按钮
    connect(panel,&EndingPanel::continueGame,this,[=](){
        for(int i=0;i<m_playerList.size();++i)
        {
            Player* player=m_playerList.at(i);
            m_contextMap[player].info->clear();
        }
        m_gameCtl->m_pendPlayer=nullptr;
        panel->close();
        panel->deleteLater();
        animation->deleteLater();
        ui->btnGroup->selectPanel(ButtonGroup::Empty);
        gameStatusPrecess(GameControl::DispatchCard);
        m_bgm->startBGM(80);
    });
}

void GamePanel::initCountDown()
{
    m_countDown=new CountDown(this);
    m_countDown->move((width()-m_countDown->width())/2,(height()-m_countDown->height())/2+30);
    connect(m_countDown,&CountDown::notMuchTime,this,[=](){
        //播放提示音
        m_bgm->playAssistMusic(BGMControl::Alert);

    });
    connect(m_countDown,&CountDown::timeout,this,&GamePanel::onUserPass);
    UserPlayer* userPlayer=m_gameCtl->getUserPlayer();
    connect(userPlayer,&UserPlayer::startCountDown,this,[=](){
        if(m_gameCtl->getPendPlayer()!=userPlayer&&m_gameCtl->getPendPlayer()!=nullptr)
        {
            m_countDown->showCountDown();
        }
    });
}



void GamePanel::paintEvent(QPaintEvent *event)
{
    QPainter painter(this);
    painter.drawPixmap(rect(),m_bkImage);

}

void GamePanel::mouseMoveEvent(QMouseEvent *ev)
{
    if(ev->buttons()&Qt::LeftButton)
    {
        QPoint point=ev->pos();
        if(!m_cardsRect.contains(point))
        {
            m_curSelCard=nullptr;
        }
        else
        {
            QList<CardPanel*> list=m_userCards.keys();
            for(int i=0;i<list.size();++i)
            {
                CardPanel* panel=list.at(i);
               if(m_userCards[panel].contains(point)&&m_curSelCard!=panel)
               {
                   panel->click();
                   m_curSelCard=panel;

               }
            }
        }
    }
}

